﻿using Microsoft.WindowsAzure.Storage.Table;
using Microsoft.WindowsAzure.Storage.Table.DataServices;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Wams.Admin;

namespace Wams.Server
{
    public class WamsInstanceState : TableEntity
    {
        public int InstanceId
        { get { return int.Parse(RowKey); } }

        public string DeploymentId
        { get { return PartitionKey; } }

        public DateTime? LastSettingsRefresh { get; set; }
        public int UpdateDomain { get; set; }
        public bool IsBusy { get; set; }
        public int InnerStatus { get; set; }
        public InstanceStatus Status
        {
            get
            {
                return (InstanceStatus)InnerStatus;
            }
            set
            {
                InnerStatus = (int)value;
                Save();
            }
        }

        public WamsInstanceState(string deploymentId, int instanceId, int updateDomain)
        {
            this.PartitionKey = deploymentId;
            this.RowKey = instanceId.ToString();
            this.UpdateDomain = updateDomain;
        }

        public WamsInstanceState() { }


        public void Save()
        {
            CloudTableClient tableClient = WamsCore.MainStorageAccount.CreateCloudTableClient();

            CloudTable table = tableClient.GetTableReference(WamsCore.ContainerName + "instances");
            try { table.CreateIfNotExists(); } catch {}

            TableOperation retrieveOperation = TableOperation.Retrieve<WamsInstanceState>(this.PartitionKey, this.RowKey);

            TableResult retrievedResult = table.Execute(retrieveOperation);

            WamsInstanceState specificEntity = (WamsInstanceState)retrievedResult.Result;
            TableOperation tOp = null;
            if (specificEntity != null)
            {
                specificEntity.InnerStatus = (int)this.Status;
                specificEntity.IsBusy = this.IsBusy;
                specificEntity.LastSettingsRefresh = this.LastSettingsRefresh;
                specificEntity.UpdateDomain = this.UpdateDomain;
                specificEntity.ETag = "*";
                tOp = TableOperation.Replace(specificEntity);
            }
            else tOp = TableOperation.Insert(this);

            table.Execute(tOp);

        }

        public void Refresh()
        {
            CloudTableClient tableClient = WamsCore.MainStorageAccount.CreateCloudTableClient();

            CloudTable table = tableClient.GetTableReference(WamsCore.ContainerName + "instances");
            table.CreateIfNotExists();

            TableOperation retrieveOperation = TableOperation.Retrieve<WamsInstanceState>(this.PartitionKey, this.RowKey);

            TableResult retrievedResult = table.Execute(retrieveOperation);

            WamsInstanceState specificEntity = (WamsInstanceState)retrievedResult.Result;

            if (specificEntity == null) return;
            InnerStatus = (int)specificEntity.Status;
        }

        public void Delete()
        {
            CloudTableClient tableClient = WamsCore.MainStorageAccount.CreateCloudTableClient();

            CloudTable table = tableClient.GetTableReference(WamsCore.ContainerName + "instances");
            table.CreateIfNotExists();

            TableOperation retrieveOperation = TableOperation.Retrieve<WamsInstanceState>(this.PartitionKey, this.RowKey);

            TableResult retrievedResult = table.Execute(retrieveOperation);

            WamsInstanceState specificEntity = (WamsInstanceState)retrievedResult.Result;

            if (specificEntity == null) return;

            TableOperation deleteOp = TableOperation.Delete(specificEntity);
            table.Execute(deleteOp);
        }

        public static void DeleteExpired()
        {
            CloudTableClient tableClient = WamsCore.MainStorageAccount.CreateCloudTableClient();

            CloudTable table = tableClient.GetTableReference(WamsCore.ContainerName + "instances");
            TableServiceContext tableServiceContext = table.ServiceClient.GetTableServiceContext();
            IQueryable<WamsInstanceState> q = (from state in tableServiceContext.CreateQuery<WamsInstanceState>(WamsCore.ContainerName + "instances")
                                               select state);

            foreach (WamsInstanceState state in q)
            {
                if (state.Timestamp >= DateTime.UtcNow.AddMinutes(-2)) continue;

                state.ETag = "*";
                TableOperation deleteOp = TableOperation.Delete(state);
                table.Execute(deleteOp);
            }
        }

    }
}